import { reactive, computed, toRefs } from "vue";
import { useUserStoreHook } from "@/store/modules/user";

const userStore = useUserStoreHook();
const { accessToken } = JSON.parse(userStore.token);

// 处理ws api方法
const appBaseList = import.meta.env.VITE_APP_WS;
const appGroup = appBaseList.split(";");
const apiList: any = [];
appGroup.map((item: string) => {
  if (item) {
    const apiObj = {
      api: item.split(",")[0],
      target: item.split(",")[1],
    };
    apiList.push(apiObj);
  }
});

/**
 * @description
 * @param {Function} dataCallBack socket接受数据后的处理参数 (必传)
 * */
export const useSocket = (dataCallBack?: (data: any) => any) => {
  const state: any = reactive({
    socketData: {},
    websocket: null,
    heartTime: null,
    socketHeart: 0, // 心跳次数
    HeartTimeOut: 30000, // 心跳超时时间
    socketError: 0, // 错误次数
  });

  function filterBaseUrl(url: any) {
    const name = url.startsWith("/") ? url.split("/")[1] : url.split("/")[0];
    const baseURL: any = apiList.filter((item: any) => item.api === name);
    return baseURL[0]?.target;
  }

  /**
   * @description 初始化 websocket
   * @return void
   * */
  const initWebSocket = async (
    api: string,
    messageContent: any = "connect"
  ) => {
    const realApi = filterBaseUrl(api);
    state.socketUrl = api;
    state.websocket = new WebSocket(realApi + api);
    websocketonopen(messageContent);
    websocketonmessage();
    websocketonerror();
    websocketclose();
    sendSocketHeart();
  };

  // socket 连接成功
  const websocketonopen = (messageContent: any) => {
    state.websocket.onopen = function (e: any) {
      const msg = {
        functionCode: "login",
        token: accessToken,
        messageType: "success",
        messageContent: messageContent,
      };
      sendMsg(msg);
      resetHeart();
    };
  };

  // socket 连接失败
  const websocketonerror = () => {
    state.websocket.onerror = function (e: any) {
      console.log("连接 websocket 失败", e);
    };
  };

  // socket 断开链接
  const websocketclose = () => {
    state.websocket.onclose = function (e: any) {
      console.log("断开连接", e);
    };
  };

  // socket 接收数据
  const websocketonmessage = () => {
    state.websocket.onmessage = function (e: any) {
      let msg = JSON.parse(e.data);
      if (msg?.messageType === "ping") {
        resetHeart();
      } else {
        dataCallBack && (msg = dataCallBack(msg));
      }
    };
  };

  // socket 发送数据
  const sendMsg = (data: any) => {
    // console.log("sendMsg", data);
    state.websocket.send(JSON.stringify(data));
  };

  // socket 重置心跳
  const resetHeart = () => {
    state.socketHeart = 0;
    state.socketError = 0;
    clearInterval(state.heartTime);
    sendSocketHeart();
  };

  // socket心跳发送
  const sendSocketHeart = () => {
    state.heartTime = setInterval(() => {
      // 如果连接正常则发送心跳
      if (state.websocket.readyState == 1) {
        // if (socketHeart <= 30) {
        state.websocket.send(
          JSON.stringify({
            functionCode: "ping",
            token: accessToken,
            messageType: "success",
            messageContent: "connect",
          })
        );
        state.socketHeart = state.socketHeart + 1;
      } else {
        // 重连
        reconnect();
      }
    }, state.HeartTimeOut);
  };

  // socket重连
  const reconnect = () => {
    if (state.socketError <= 2) {
      clearInterval(state.heartTime);
      initWebSocket(state.socketUrl);
      state.socketError = state.socketError + 1;
    } else {
      clearInterval(state.heartTime);
    }
  };

  return {
    ...toRefs(state),
    initWebSocket,
    websocketclose,
  };
};
